In [1]:
import pandas as pd
import plotly.express as px
import numpy as np
from plotly.subplots import make_subplots
In [2]:
# Loading data from Global Witness (https://www.globalwitness.org/en/campaigns/environmental-activists/numbers-lethal-attacks-against-defenders-2012/)
gw_data = pd.read_csv("global_witness_led_22-09-22.csv")
In [3]:
gw_data.columns
Out[3]:
Index(['id', 'date', 'name', 'gender', 'age', 'person_characteristics',
'industry_driver', 'perpetrator_type', 'continent', 'country',
'country_numeric', 'local_region', 'number_of_victims'],
dtype='object')
In [4]:
gw_data.shape
Out[4]:
(1733, 13)
In [5]:
gw_data.head(10).style\
.hide(axis="columns", subset=["id", "country_numeric"])\
.hide(axis="index")\
.set_properties(**{'background-color': 'RGBA(232, 232, 250, .5)',
'border': '1.5px solid white',
'color': '#495057'})\
.set_table_styles(
[{'selector': 'tr:hover',
'props': [('background-color', '#fffacd')]},
{'selector': 'th',
'props': [('background-color', 'RGBA(180, 142, 173, .5)')]}]
)
Out[5]:
| date | name | gender | age | person_characteristics | industry_driver | perpetrator_type | continent | country | local_region | number_of_victims |
|---|---|---|---|---|---|---|---|---|---|---|
| 2016-02-18 | Aníbal Coronado Madera | Male | 49.000000 | Other | Sector could not be confirmed* | Private military actors | Americas | Colombia | Córdoba | 1 |
| 2016-10-16 | Yimer Chávez Rivera | Male | 31.000000 | Small-scale farmer | Sector could not be confirmed* | Private military actors | Americas | Colombia | Cauca | 1 |
| 2015-02-10 | Héctor William Cabrera Suárez | Male | 58.000000 | Other | Sector could not be confirmed* | Unspecified | Americas | Colombia | Caquetá | 1 |
| 2016-04-27 | Rolan Lonin Casiano | Male | 32.000000 | Small-scale farmer | Sector could not be confirmed* | Armed forces | Asia | Philippines | Bicol | 1 |
| 2015-05-22 | Benilda Santos | Female | 43.000000 | nan | Sector could not be confirmed* | Unspecified | Asia | Philippines | Quezon City | 1 |
| 2016-08-29 | Diego Alfredo Chirán Nastacuas | Male | 24.000000 | Indigenous peoples | Sector could not be confirmed* | Unspecified | Americas | Colombia | Nariño | 1 |
| 2014-04-21 | Luis Javier Campo Méndez | Male | 22.000000 | Indigenous peoples | Sector could not be confirmed* | Unspecified | Americas | Colombia | nan | 1 |
| 2016-12-30 | Yaneth Alejandra Calvache Viveros | Female | nan | Small-scale farmer | Sector could not be confirmed* | Hitmen | Americas | Colombia | Cauca | 1 |
| 2017-10-24 | Aulio Isarama Forastero | Male | nan | Indigenous peoples | Sector could not be confirmed* | Private military actors | Americas | Colombia | Chocó | 1 |
| 2016-05-20 | Manuel Chimá Pérez | Male | 21.000000 | Indigenous peoples | Sector could not be confirmed* | Private military actors | Americas | Colombia | Antioquia | 1 |
In [6]:
gw_data.number_of_victims.unique()
# Making sure each row records one attack/victim
Out[6]:
array([1])
About the victims¶
In [7]:
gw_data["gender"].value_counts()
Out[7]:
gender Male 1545 Female 183 Unknown 1 Name: count, dtype: int64
In [8]:
gender_data = {
"gender": [ "Male", "Female", "unknown"],
"count": [1545, 183, 1]
}
gender_df = pd.DataFrame(gender_data)
In [9]:
treemap_gender = px.treemap(gender_df,
path=['gender'], values='count', color='gender', hover_name='count',
color_discrete_sequence=["#81a1c1", "#a3be8c", "#b48ead", "#b48ead"])
In [10]:
scatter_df = gw_data[["age", "gender", "person_characteristics", "number_of_victims", "industry_driver", "continent"]]
#scatter_df.head()
# Age data error: 4145
#scatter_df[scatter_df.age > 90]
# I assume it's a typo and should be 41
fixed_df = scatter_df.replace(to_replace=4145.0, value=41)
In [11]:
hist_age_gender = px.histogram(fixed_df, x="age", nbins=20,
color_discrete_sequence=["#81a1c1", "#a3be8c", "#b48ead"], color="gender")
In [12]:
bar_characteristic = px.bar(fixed_df, x='person_characteristics', y='number_of_victims',
color="gender", color_discrete_sequence=["#0354A4", "#0A9623", "#f08c00"],
hover_data="age", hover_name="person_characteristics")
In [13]:
treemap_gender.update_traces(textinfo="label+percent root")
hist_age_gender.update_traces(legendgroup="1")
bar_characteristic.update_traces(showlegend=False)
fig1_traces, fig2_traces, fig3_traces = [], [], []
for trace in range(len(treemap_gender["data"])):
fig1_traces.append(treemap_gender["data"][trace])
for trace in range(len(hist_age_gender["data"])):
fig2_traces.append(hist_age_gender["data"][trace])
for trace in range(len(bar_characteristic["data"])):
fig3_traces.append(bar_characteristic["data"][trace])
fig_gender = make_subplots(specs=[[{"type": "domain"}, None], [{"type": "xy"}, {"type": "xy"}]],
cols=2, rows=2, column_widths=[0.5, 0.5], row_heights=[0.35, 0.65],
subplot_titles=('Attacks victims are men in majority', 'Victims are mostly adults between 20-60', 'Indigenous people overrepresented among victims'))
for traces in fig1_traces:
fig_gender.add_trace(traces, row=1, col=1)
for traces in fig2_traces:
fig_gender.add_trace(traces, row=2, col=1)
for traces in fig3_traces:
fig_gender.add_trace(traces, row=2, col=2)
fig_gender.update_layout(
template="plotly_white",
title="Victims distributed by gender, age and personal characteristic (data source: www.globalwitness.org)",
xaxis= {"title": 'Age'}, yaxis= {"title": 'Number of victims'},
showlegend=True,
legend={"title": "Gender", "yanchor":"bottom", "y":0.3, "xanchor":"right", "x":0.45},
legend_tracegroupgap = 50,
barmode='relative',
margin=dict(r=5, t=80, b=5, l=5))
fig_gender.update_layout(
autosize=False,
width=1200,
height=700)
fig_gender.show()
What about the children?¶
In [14]:
bar_child_characteristic = px.bar(fixed_df[fixed_df['age'] < 18], x='person_characteristics', y='number_of_victims',
color="industry_driver", color_discrete_sequence=["#6A3E75", "#40c057", "#f08c00", "#3bc9db", "#ff6b6b", "#9775fa"],
hover_data="age", hover_name="person_characteristics", barmode="relative")
bar_child_characteristic2 = px.bar(fixed_df[fixed_df['age'] < 18], x='person_characteristics', y='number_of_victims',
color="continent", color_discrete_sequence=["#b48ead", "#a3be8c"],
hover_data="age", hover_name="person_characteristics", barmode="relative")
In [15]:
hist_age_gender.update_traces(legendgroup="1")
hist_age_gender.update_traces(legendgroup="2")
fig4_traces, fig5_traces = [], []
for trace in range(len(bar_child_characteristic["data"])):
fig4_traces.append(bar_child_characteristic["data"][trace])
for trace in range(len(bar_child_characteristic2["data"])):
fig5_traces.append(bar_child_characteristic2["data"][trace])
fig_child = make_subplots(specs=[[{"type": "xy"}, {"type": "xy"}]], cols=2, rows=1)
for traces in fig4_traces:
fig_child.add_trace(traces, row=1, col=1)
for traces in fig5_traces:
fig_child.add_trace(traces, row=1, col=2)
fig_child.update_layout(
template="plotly_white",
title="Most children victims are indigenous of (the) America(s) close to mining activities (data source: www.globalwitness.org)",
yaxis= {"title": 'Number of victims'},
showlegend=True,
legend={"title": "Legend", "yanchor":"top", "y":1.2, "xanchor":"right", "x":1.3},
legend_tracegroupgap = 4,
barmode='relative',
margin=dict(r=5, t=80, b=5, l=5)
)
fig_child.update_layout(
autosize=False,
width=1200,
height=400)
fig_child.show()
What about the elderly?¶
In [28]:
bar_elder_characteristic = px.bar(fixed_df[fixed_df['age'] > 60], x='person_characteristics', y='number_of_victims',
color="industry_driver", hover_data="age", hover_name="person_characteristics", barmode="relative",
color_discrete_sequence=["#6A3E75", "#40c057", "#f08c00", "#3bc9db", "#ff6b6b", "#9775fa", "#f06595", "#ffd43b"])
bar_elder_characteristic2 = px.bar(fixed_df[fixed_df['age'] > 60], x='person_characteristics', y='number_of_victims',
color="continent", color_discrete_sequence=["#a3be8c", "#b48ead", "#81a1c1", "#d08770"],
hover_data="age", hover_name="person_characteristics", barmode="relative")
In [29]:
fig6_traces, fig7_traces = [], []
for trace in range(len(bar_elder_characteristic["data"])):
fig6_traces.append(bar_elder_characteristic["data"][trace])
for trace in range(len(bar_elder_characteristic2["data"])):
fig7_traces.append(bar_elder_characteristic2["data"][trace])
fig_elder = make_subplots(specs=[[{"type": "xy"}, {"type": "xy"}]],
cols=2, rows=1)
for traces in fig6_traces:
fig_elder.add_trace(traces, row=1, col=1)
for traces in fig7_traces:
fig_elder.add_trace(traces, row=1, col=2)
fig_elder.update_layout(
template="plotly_white",
title="Most elderly victims are indigenous people and/or small-scale farmers of (the) America(s) close to mining activities (data source: www.globalwitness.org)",
yaxis= {"title": 'Number of victims'},
showlegend=True,
legend={"title": "Legend", "yanchor":"top", "y":1.0, "xanchor":"right", "x":1.3},
legend_tracegroupgap = 4,
barmode='relative',
margin=dict(r=5, t=80, b=5, l=5),)
fig_elder.update_layout(
autosize=False,
width=1200,
height=500)
fig_elder.show()
Where in the world?¶
In [18]:
num_attacks = gw_data.shape[0]
continents_attacks = ", ".join(gw_data["continent"].unique())
f'There were {num_attacks} attacks across {continents_attacks} between 2012 and 2021, according to the NGO Global Witness.'
Out[18]:
'There were 1733 attacks across Americas, Asia, Africa, Oceania, Europe between 2012 and 2021, according to the NGO Global Witness.'
In [19]:
countries_attacks = gw_data["country"].unique()
most_attacks = gw_data["country"].value_counts()[:3]
f'Attacks occured in {len(countries_attacks)} countries.'
f'The highest number of attacks happened in {most_attacks.index[0]} ({most_attacks[0]} attacks), {most_attacks.index[1]} ({most_attacks[1]} attacks) \
and the {most_attacks.index[2]} ({most_attacks[2]} attacks).'
Out[19]:
'The highest number of attacks happened in Brazil (342 attacks), Colombia (322 attacks) and the Philippines (270 attacks).'
In [20]:
countries_and_continents = gw_data[["country", "continent", "number_of_victims"]]
In [21]:
treemap_countries = px.treemap(countries_and_continents,
path=[px.Constant("world"), 'continent', 'country'], values='number_of_victims',
color='country', hover_name='number_of_victims',
color_discrete_sequence=["#81a1c1", "#a3be8c", "#b48ead", "#ebcb8b", "#d08770", "#88c0d0", "#bf616a"],
width=1000, height=800, title="Victims by countries"
)
treemap_countries.update_traces(textinfo="label+value")
treemap_countries.update_layout(margin = dict(t=50, l=25, r=25, b=25))
treemap_countries.show()
In [22]:
victims_by_country = gw_data[["country", "number_of_victims"]].groupby(by="country", as_index=False).sum()
In [23]:
map_victims = px.choropleth(
victims_by_country, locations="country",
locationmode="country names",
color='number_of_victims',
color_continuous_scale="sunsetdark",
title="Lethal attacks of land defenders worlwide (2012-2021)",
projection="natural earth"
)
map_victims.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
map_victims.show()
About the causes & perpetrators¶
In [77]:
#gw_data[["perpetrator_type", "continent", "number_of_victims"]].value_counts()
In [24]:
bar_industry = px.bar(gw_data, y='industry_driver', x='number_of_victims', width=600, height=600,
color="continent", color_discrete_sequence=["#8a2be2", "#087f5b", "#f08c00", "#364fc7", "#c2255c"],
hover_data="age", hover_name="industry_driver", orientation='h',
title="Attacks by industry associated")
bar_perpetrator = px.bar(gw_data, y='perpetrator_type', x='number_of_victims', width=600, height=600,
color="continent", color_discrete_sequence=["#8a2be2", "#087f5b", "#f08c00", "#364fc7", "#c2255c"],
hover_data="age", hover_name="perpetrator_type", orientation='h',
title="Attacks by type of perpetrators")
In [25]:
bar_perpetrator.update_traces(showlegend=False)
fig8_traces, fig9_traces = [], []
for trace in range(len(bar_industry["data"])):
fig8_traces.append(bar_industry["data"][trace])
for trace in range(len(bar_perpetrator["data"])):
fig9_traces.append(bar_perpetrator["data"][trace])
fig_causes = make_subplots(specs=[[{"type": "xy"}, {"type": "xy"}]], cols=2, rows=1,
column_widths=[0.5, 0.5], x_title='Number of victims')
for traces in fig8_traces:
fig_causes.add_trace(traces, row=1, col=1)
for traces in fig9_traces:
fig_causes.add_trace(traces, row=1, col=2)
fig_causes.update_layout(
template="plotly_white",
title="Indentified perpetrators are mostly hitmen in America(s), armed forces in Asia, private military actors in Africa (data source: www.globalwitness.org)",
xaxis= {"title": ''},
showlegend=True,
legend={"title": "Continents", "yanchor":"top", "y":1.0, "xanchor":"right", "x":0.35},
legend_tracegroupgap = 2,
barmode='relative',
margin=dict(r=5, t=75, b=50, l=5)
)
fig_causes.update_layout(
autosize=False,
width=1300,
height=500)
fig_causes.show()
Attacks over time¶
In [26]:
# Transform dates to datetime format
gw_df = gw_data.copy()
gw_df['date'] = pd.to_datetime(gw_df['date'], errors='coerce')
In [27]:
yearly_bar = px.bar(gw_df, x=gw_df["date"].dt.year, y='number_of_victims', width=900, height=600,
title="Attacks against land defenders seem on an increasing trend globally", labels={"x": "year"}, range_x=[2012, 2021],
color="continent", color_discrete_sequence=["#b48ead", "#a3be8c", "#ebcb8b", "#81a1c1", "#d08770"]
)
yearly_bar.show()
The lethal attacks against land defenders are either getting more frequent or better documented (or both).
At a time where the consequences of the climate emergency get even more visible, some corporations double down on resources extraction (fossil-fuel, minerals),
deforestation for large scale agriculture... The land defenders (mostly indigenous people in Brazil, Colombia and The Philippines) are at increased risk for their lives.
In [ ]: